#include "app_pool.h"
#include <mqueue.h>
#include <unistd.h>
#include <pthread.h>
#include <fcntl.h>
#include <stdio.h>
#include "log.h"

static mqd_t mq ;
static pthread_t pool_threads[POOL_THREAD_NUM];


/**
 * @brief 线程处理任务
 *   1 不停地从队列中取出任务
 *   2 拆解任务 -> 函数 和  参数
 *   3 执行任务
 */
void *app_pool_handle_task(void *arg)
{
    while (1)
    {
        app_pool_task_t task;
        mq_receive(mq, (char *)&task, sizeof(app_pool_task_t), NULL);
        task.func(task.arg);
    }
}


/**
 * @brief 初始化线程池
 *   1 先创建队列
 *   2 再创建线程池
 */
int app_pool_init()
{
    //0  清理掉旧的队列
    mq_unlink(POOL_QUEUE_NAME);
    // *   1 先创建队列
    struct mq_attr attr;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = sizeof(app_pool_task_t);   

    mq = mq_open(POOL_QUEUE_NAME, O_RDWR | O_CREAT, 0666, &attr);
    if(mq == -1)
    {
        perror("mq_open failed");
        return -1;
    }

    // *   2 逐个创建线程池
    for (size_t i = 0; i < POOL_THREAD_NUM; i++)
    {
        pthread_create(&pool_threads[i], NULL, app_pool_handle_task, NULL);
    }
    return 0;
}


/**
 * @brief 向线程池提交 任务 （函数指针，参数）
 */
int app_pool_submit_task(void *(*func)(void *), void *arg)
{   //1 把函数和参数封装成任务 --> 任务结构体
    app_pool_task_t task;
    task.func = func;
    task.arg = arg;
    //2 把结构体交给提交给队列
     int ret= mq_send(mq, (char *)&task, sizeof(app_pool_task_t), 0);
    if(ret == 0)
    {
        log_info(" task submit success");
        return 0;
    }else
    {
        perror(" task submit failed");
        return -1;
    }

}

/**
 * @brief 销毁线程池
 *  把线程逐个 cancel 
 *  关闭队列
 *  删除队列
 */
void app_pool_destroy()
{
    //1 把线程逐个 cancel
    for (size_t i = 0; i < POOL_THREAD_NUM; i++)
    {
        pthread_cancel(pool_threads[i]);
    }
    //2 关闭队列
    mq_close(mq);
    //3 删除队列
    mq_unlink(POOL_QUEUE_NAME); 
}